package core

import (
	"encoding/base64"
	"encoding/json"
	"strconv"
	"strings"
)

const (
	HTTP_HEADER_ACCEPT                           = "Accept"
	HTTP_HEADER_ACCEPT_CHARSET                   = "Accept-Charset"
	HTTP_HEADER_ACCEPT_ENCODING                  = "Accept-Encoding"
	HTTP_HEADER_ACCEPT_LANGUAGE                  = "Accept-Language"
	HTTP_HEADER_ACCEPT_RANGES                    = "Accept-Ranges"
	HTTP_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials"
	HTTP_HEADER_ACCESS_CONTROL_ALLOW_HEADERS     = "Access-Control-Allow-Headers"
	HTTP_HEADER_ACCESS_CONTROL_ALLOW_METHODS     = "Access-Control-Allow-Methods"
	HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN      = "Access-Control-Allow-Origin"
	HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS    = "Access-Control-Expose-Headers"
	HTTP_HEADER_ACCESS_CONTROL_MAX_AGE           = "Access-Control-Max-Age"
	HTTP_HEADER_ACCESS_CONTROL_REQUEST_HEADERS   = "Access-Control-Request-Headers"
	HTTP_HEADER_ACCESS_CONTROL_REQUEST_METHOD    = "Access-Control-Request-Method"
	HTTP_HEADER_AGE                              = "Age"
	HTTP_HEADER_ALLOW                            = "Allow"
	HTTP_HEADER_AUTHORIZATION                    = "Authorization"
	HTTP_HEADER_CACHE_CONTROL                    = "Cache-Control"
	HTTP_HEADER_CONNECTION                       = "Connection"
	HTTP_HEADER_CONTENT_ENCODING                 = "Content-Encoding"
	HTTP_HEADER_CONTENT_DISPOSITION              = "Content-Disposition"
	HTTP_HEADER_CONTENT_LANGUAGE                 = "Content-Language"
	HTTP_HEADER_CONTENT_LENGTH                   = "Content-Length"
	HTTP_HEADER_CONTENT_LOCATION                 = "Content-Location"
	HTTP_HEADER_CONTENT_RANGE                    = "Content-Range"
	HTTP_HEADER_CONTENT_TYPE                     = "Content-Type"
	HTTP_HEADER_COOKIE                           = "Cookie"
	HTTP_HEADER_DATE                             = "Date"
	HTTP_HEADER_ETAG                             = "ETag"
	HTTP_HEADER_EXPECT                           = "Expect"
	HTTP_HEADER_EXPIRES                          = "Expires"
	HTTP_HEADER_FROM                             = "From"
	HTTP_HEADER_HOST                             = "Host"
	HTTP_HEADER_IF_MATCH                         = "If-Match"
	HTTP_HEADER_IF_MODIFIED_SINCE                = "If-Modified-Since"
	HTTP_HEADER_IF_NONE_MATCH                    = "If-None-Match"
	HTTP_HEADER_IF_RANGE                         = "If-Range"
	HTTP_HEADER_IF_UNMODIFIED_SINCE              = "If-Unmodified-Since"
	HTTP_HEADER_LAST_MODIFIED                    = "Last-Modified"
	HTTP_HEADER_LINK                             = "Link"
	HTTP_HEADER_LOCATION                         = "Location"
	HTTP_HEADER_MAX_FORWARDS                     = "Max-Forwards"
	HTTP_HEADER_ORIGIN                           = "Origin"
	HTTP_HEADER_PRAGMA                           = "Pragma"
	HTTP_HEADER_PROXY_AUTHENTICATE               = "Proxy-Authenticate"
	HTTP_HEADER_PROXY_AUTHORIZATION              = "Proxy-Authorization"
	HTTP_HEADER_RANGE                            = "Range"
	HTTP_HEADER_REFERER                          = "Referer"
	HTTP_HEADER_RETRY_AFTER                      = "Retry-After"
	HTTP_HEADER_SERVER                           = "Server"
	HTTP_HEADER_SET_COOKIE                       = "Set-Cookie"
	HTTP_HEADER_SET_COOKIE2                      = "Set-Cookie2"
	HTTP_HEADER_TE                               = "TE"
	HTTP_HEADER_TRAILER                          = "Trailer"
	HTTP_HEADER_TRANSFER_ENCODING                = "Transfer-Encoding"
	HTTP_HEADER_UPGRADE                          = "Upgrade"
	HTTP_HEADER_USER_AGENT                       = "User-Agent"
	HTTP_HEADER_VARY                             = "Vary"
	HTTP_HEADER_VIA                              = "Via"
	HTTP_HEADER_WARNING                          = "Warning"
	HTTP_HEADER_WWW_AUTHENTICATE                 = "WWW-Authenticate"
)

type HttpHeaders struct {
	headers map[string][]string
}

func (h *HttpHeaders) Add(headerName string, headerValue string) {
	if h.headers[headerName] == nil {
		h.headers[headerName] = make([]string, 1)
	}
	h.headers[headerName] = append(h.headers[headerName], headerValue)
}
func (h *HttpHeaders) AddAll(headerName string, values []string) {
	h.headers[headerName] = values

}
func (h *HttpHeaders) AddMap(values map[string][]string) {
	for k, v := range values {
		h.headers[k] = v
	}
}
func (h *HttpHeaders) Clear() {
	h.headers = make(map[string][]string)
}

func (h *HttpHeaders) ClearContentHeaders() {
	delete(h.headers, HTTP_HEADER_CONTENT_DISPOSITION)
	delete(h.headers, HTTP_HEADER_CONTENT_DISPOSITION)
	delete(h.headers, HTTP_HEADER_CONTENT_ENCODING)
	delete(h.headers, HTTP_HEADER_CONTENT_LANGUAGE)
	delete(h.headers, HTTP_HEADER_CONTENT_LENGTH)
	delete(h.headers, HTTP_HEADER_CONTENT_LOCATION)
	delete(h.headers, HTTP_HEADER_CONTENT_RANGE)
	delete(h.headers, HTTP_HEADER_CONTENT_TYPE)
}
func (h *HttpHeaders) ContainsKey(headerName string) bool {
	return h.headers[headerName] != nil
}

func (h *HttpHeaders) EncodeBasicAuth(username string, password string) string {
	credentialsString := username + ":" + password
	return base64.StdEncoding.EncodeToString([]byte(credentialsString))
}
func (h *HttpHeaders) Get(headerName string) []string {
	return h.headers[headerName]
}

func (h *HttpHeaders) getAccept() []MediaType {
	list := h.Get(HTTP_HEADER_ACCEPT)
	if list != nil {
		types := make([]MediaType, len(list))
		for i := range list {
			types[i] = MediaType(list[i])
		}
		return types
	}
	return nil
}

func (h *HttpHeaders) GetAcceptCharset() []string {
	v := h.GetFirst(HTTP_HEADER_ACCEPT_CHARSET)
	if v == "" {
		return nil
	}
	ll := strings.Split(v, ",")
	charsets := make([]string, 0)
	index := 0
	for _, value := range ll {
		paramIdx := strings.Index(value, ";")
		charset := ""
		if paramIdx == -1 {
			charset = value
		} else {
			charset = value[0:paramIdx]
		}
		if charset != "*" {
			charsets[index] = charset
			index++
		}
	}
	return charsets

}
func (h *HttpHeaders) getAcceptLanguage() string {
	return h.GetFirst(HTTP_HEADER_ACCEPT_LANGUAGE)
}
func (h *HttpHeaders) getAccessControlAllowCredentials() bool {
	v := h.GetFirst(HTTP_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS)
	if v == "" {
		return false
	}
	f, err := strconv.ParseBool(v)
	if err != nil {
		return false
	}
	return f
}
func (h *HttpHeaders) getAccessControlAllowHeaders() []string {
	return h.Get(HTTP_HEADER_ACCESS_CONTROL_ALLOW_HEADERS)
}
func (h *HttpHeaders) getAccessControlAllowMethods() []string {
	return h.Get(HTTP_HEADER_ACCESS_CONTROL_ALLOW_METHODS)
}
func (h *HttpHeaders) getAccessControlAllowOrigin() string {
	list := h.Get(HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN)
	if list == nil {
		return ""
	}
	v, err := json.Marshal(list)
	if err != nil {
		return ""
	}
	return string(v)
}

func (h *HttpHeaders) getAccessControlExposeHeaders() []string {
	return h.Get(HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS)
}
func (h *HttpHeaders) getAccessControlMaxAge() {

}
func (h *HttpHeaders) getAccessControlRequestHeaders() {

}
func (h *HttpHeaders) getAccessControlRequestMethod() {

}
func (h *HttpHeaders) getAllow() {

}
func (h *HttpHeaders) getCacheControl() {

}
func (h *HttpHeaders) getConnection() {

}
func (h *HttpHeaders) getContentDisposition() {

}
func (h *HttpHeaders) getContentLanguage() {

}
func (h *HttpHeaders) getContentLength() {

}
func (h *HttpHeaders) GetContentType() MediaType {
	value := h.GetFirst(HTTP_HEADER_CONTENT_TYPE)
	if value != "" {
		return MediaType(value)
	}
	return ""
}
func (h *HttpHeaders) getDate() {

}
func (h *HttpHeaders) getETag() {

}
func (h *HttpHeaders) getETagValuesAsList() {

}
func (h *HttpHeaders) getExpires() {

}
func (h *HttpHeaders) getFieldValues() {

}
func (h *HttpHeaders) GetFirst(headerName string) string {
	list := h.headers[headerName]
	if list != nil && len(list) > 0 {
		return list[0]
	}
	return ""
}
func (h *HttpHeaders) GetFirstDate(headerName string) {

}
func (h *HttpHeaders) getFirstDate(headerName string, rejectInvalid bool) {

}
func (h *HttpHeaders) GetFirstZonedDateTime(headerName string) {

}
func (h *HttpHeaders) getFirstZonedDateTime(headerName string, rejectInvalid bool) {

}
func (h *HttpHeaders) getHost() {

}
func (h *HttpHeaders) getIfMatch() {

}
func (h *HttpHeaders) getIfModifiedSince() {

}
func (h *HttpHeaders) getIfNoneMatch() {

}
func (h *HttpHeaders) getIfUnmodifiedSince() {

}
func (h *HttpHeaders) getLastModified() {

}
func (h *HttpHeaders) getLocation() {

}
func (h *HttpHeaders) getOrEmpty() {

}
func (h *HttpHeaders) getOrigin() {

}
func (h *HttpHeaders) getPragma() {

}
func (h *HttpHeaders) getRange() {

}
func (h *HttpHeaders) getUpgrade() {

}
func (h *HttpHeaders) getVary() {

}
func (h *HttpHeaders) hashCode() {

}
func (h *HttpHeaders) isEmpty() {

}
func (h *HttpHeaders) keySet() []string {
	i := 0
	keys := make([]string, len(h.headers))
	for key := range h.headers {
		keys[i] = key
		i++
	}
	return keys
}
func (h *HttpHeaders) put() {

}
func (h *HttpHeaders) putAll() {

}
func (h *HttpHeaders) readOnlyHttpHeaders() {

}
func (h *HttpHeaders) remove() {

}
func (h *HttpHeaders) set() {

}
func (h *HttpHeaders) setAccept() {

}
func (h *HttpHeaders) setAcceptCharset() {

}
func (h *HttpHeaders) setAcceptLanguage() {

}
func (h *HttpHeaders) setAcceptLanguageAsLocales() {

}
func (h *HttpHeaders) setAccessControlAllowCredentials() {

}
func (h *HttpHeaders) setAccessControlAllowHeaders() {

}
func (h *HttpHeaders) setAccessControlAllowMethods() {

}
func (h *HttpHeaders) setAccessControlAllowOrigin() {

}
func (h *HttpHeaders) setAccessControlExposeHeaders() {

}
func (h *HttpHeaders) setAccessControlMaxAge() {

}
func (h *HttpHeaders) setAccessControlRequestHeaders() {

}
func (h *HttpHeaders) setAccessControlRequestMethod() {

}
func (h *HttpHeaders) setAll() {

}
func (h *HttpHeaders) setAllow() {

}
func (h *HttpHeaders) setBasicAuth() {

}
func (h *HttpHeaders) setBasicAuth() {

}
func (h *HttpHeaders) setBasicAuth() {

}
func (h *HttpHeaders) setBearerAuth() {

}
func (h *HttpHeaders) setCacheControl() {

}
func (h *HttpHeaders) setCacheControl() {

}
func (h *HttpHeaders) setConnection() {

}
func (h *HttpHeaders) setConnection() {

}
func (h *HttpHeaders) setContentDisposition() {

}
func (h *HttpHeaders) setContentDispositionFormData() {

}
func (h *HttpHeaders) setContentLanguage() {

}
func (h *HttpHeaders) setContentLength() {

}
func (h *HttpHeaders) setContentType() {

}
func (h *HttpHeaders) setDate() {

}
func (h *HttpHeaders) setDate() {

}
func (h *HttpHeaders) setDate() {

}
func (h *HttpHeaders) setDate() {

}
func (h *HttpHeaders) setETag() {

}
func (h *HttpHeaders) setExpires() {

}
func (h *HttpHeaders) setExpires() {

}
func (h *HttpHeaders) setExpires() {

}
func (h *HttpHeaders) setHost() {

}
func (h *HttpHeaders) setIfMatch() {

}
func (h *HttpHeaders) setIfMatch() {

}
func (h *HttpHeaders) setIfModifiedSince() {

}
func (h *HttpHeaders) setIfModifiedSince() {

}
func (h *HttpHeaders) setIfModifiedSince() {

}
func (h *HttpHeaders) setIfNoneMatch() {

}
func (h *HttpHeaders) setIfNoneMatch() {

}
func (h *HttpHeaders) setIfUnmodifiedSince() {

}
func (h *HttpHeaders) setIfUnmodifiedSince() {

}
func (h *HttpHeaders) setIfUnmodifiedSince() {

}
func (h *HttpHeaders) setInstant() {

}
func (h *HttpHeaders) setLastModified() {

}
func (h *HttpHeaders) setLastModified() {

}
func (h *HttpHeaders) setLastModified() {

}
func (h *HttpHeaders) setLocation() {

}
func (h *HttpHeaders) setOrigin() {

}
func (h *HttpHeaders) setOrRemove() {

}
func (h *HttpHeaders) setPragma() {

}
func (h *HttpHeaders) setRange() {

}
func (h *HttpHeaders) setUpgrade() {

}
func (h *HttpHeaders) setVary() {

}
func (h *HttpHeaders) setZonedDateTime() {

}
func (h *HttpHeaders) Size() int {
	return len(h.headers)
}
func (h *HttpHeaders) toCommaDelimitedString() {

}
func (h *HttpHeaders) toSingleValueMap() {

}
func (h *HttpHeaders) toString() {

}
func (h *HttpHeaders) values() {

}
func (h *HttpHeaders) writableHttpHeaders() {

}
